﻿using Yxinmt.Interface;
using Yxinmt.Utility;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;

namespace Yxinmt.Controls
{
    public class ImageTextButton : BaseControl, IControl
    {
        StackPanel _StackPanel { get; set; }
        DockPanel _DockPanel { get; set; }
        Image _Image { get; set; }
        DockPanel _DockPanelImage { get; set; }
        Label _Label { get; set; }
        TextBlock _TextBlock { get; set; }

        private System.Windows.Controls.Button _Button { get; set; }

        public ImageTextButton(Dictionary<string, object> property, IComponent component)
        {
            Property = property;
            _Component = component;
            _Button = new System.Windows.Controls.Button();
            this.Element = _Button;

            _NoContainNameList = new List<string>();
            InitSet();
            SetProperty();
            SetControlProperty();

            this.SetButtonStyle();
        }

        private void SetButtonStyle()
        {
            Dictionary<string, object> property = new Dictionary<string, object>();
            if (Property.ContainsKey("PanelMargin")) property["Margin"] = Property["PanelMargin"];
            this.SetPropertyKvp(new List<string> { "name", "Flow", "Width", "Height", "Margin", "Dock", "ControlAlign", "BackColor", "BackImageUrl", "BackImageStretch", "IsHorizontal" }, property);

            if (Property.GetStringValue("PanelType") == "DockPanel") _DockPanel = new DockPanel(property, _Component, true);
            else _StackPanel = new StackPanel(property, _Component, true);
            var factory = _StackPanel != null ? _StackPanel.GetFactory() : _DockPanel.GetFactory();

            _PanelFullName = _StackPanel != null ? _StackPanel.FullName : _DockPanel.FullName;

            if (Property.ContainsKey("ImageUrl"))
            {
                property = new Dictionary<string, object>();
                if (Property.ContainsKey("ImageMargin")) property["Margin"] = Property["ImageMargin"];
                if (Property.ContainsKey("ImageAlign")) property["ControlAlign"] = Property["ImageAlign"];

                this.SetPropertyKvp(new List<string> { "name", "ImageUrl", "Margin", "ImageWidth", "ImageHeight", "Stretch" }, property);
                _Image = new Image(property, _Component, true);
                factory.AppendChild(_Image.GetFactory());
            }

            if (Property.ContainsKey("DockPanelImage"))
            {
                property = Property.GetValue<Dictionary<string, object>>("DockPanelImage");

                _DockPanelImage = new DockPanel(property, _Component, true);

                var dockFactory = _DockPanelImage.GetFactory();

                Dictionary<string, object> propertyImage = new Dictionary<string, object>();
                propertyImage["name"] = string.Format("Img_{0}", property.GetStringValue("name"));
                propertyImage["ImageUrl"] = property["ImageUrl"];

                if (property.ContainsKey("ImageWidth")) propertyImage["ImageWidth"] = property["ImageWidth"];
                if (property.ContainsKey("ImageWidth")) propertyImage["ImageWidth"] = property["ImageWidth"];
                if (property.ContainsKey("Stretch")) propertyImage["Stretch"] = property["Stretch"];

                var img = new Image(propertyImage, _Component, true);
                dockFactory.AppendChild(img.GetFactory());

                factory.AppendChild(dockFactory);
            }

            if (!string.IsNullOrEmpty(Property.GetStringValue("Text")) || !string.IsNullOrEmpty(Property.GetStringValue("Label")) || Property.GetValue<bool>("IsEmptyLabel"))
            {
                property = new Dictionary<string, object>();

                if (Property.GetValue<bool>("IsEmptyLabel"))
                {
                    property["Label"] = string.Empty;
                }

                if (Property.ContainsKey("LabelHeight")) property["Height"] = Property["LabelHeight"];
                if (Property.ContainsKey("LabelWidth")) property["ControlWidth"] = Property["LabelWidth"];
                if (Property.ContainsKey("LabelBackColor")) property["BackColor"] = Property["LabelBackColor"];
                if (Property.ContainsKey("LabelMargin")) property["Margin"] = Property["LabelMargin"];
                if (Property.ContainsKey("LabelPadding")) property["Padding"] = Property["LabelPadding"];

                this.SetPropertyKvp(new List<string> { "name", "LabelWidth", "ControlWidth", "Height", "Label", "Text", "TextWrapping", "Margin", "IsDefaultValue", "BackColor", "FontColor", "FontSize", "TextAlign", "Padding" }, property);
                if (!string.IsNullOrEmpty(Property.GetStringValue("Text")))
                {
                    _TextBlock = new TextBlock(property, _Component, true);
                    factory.AppendChild(_TextBlock.GetFactory());
                }
                else
                {
                    _Label = new Label(property, _Component, true);
                    factory.AppendChild(_Label.GetFactory());
                }
            }

            System.Windows.Controls.ControlTemplate template = new System.Windows.Controls.ControlTemplate() { VisualTree = factory };

            this.SetTriggers(template.Triggers);

            template.Seal();

            _Button.Template = template;

            //string xamlString = System.Windows.Markup.XamlWriter.Save(_Button);
        }

        public override void SetBackColor(string color)
        {
            color = string.IsNullOrEmpty(color) ? "Transparent" : color;

            var panel = (System.Windows.Controls.Panel)_Button.Template.FindName(_PanelFullName, _Button);
            if (panel != null) panel.Background = GetColor(color);
        }

        string _PanelFullName { get; set; }

        private void SetTriggers(System.Windows.TriggerCollection triggers)
        {
            System.Windows.Trigger trigger = null;
            if (Property.GetValue<bool>("IsMouseOver"))
            {
                trigger = new System.Windows.Trigger() { Property = System.Windows.Controls.Button.IsMouseOverProperty, Value = true };

                if (Property.ContainsKey("MouseOverImageUrl"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _Image.FullName;
                    setter.Property = System.Windows.Controls.Image.SourceProperty;
                    setter.Value = this.GetImage(Property.GetStringValue("MouseOverImageUrl"));
                    trigger.Setters.Add(setter);
                }

                if (Property.ContainsKey("MouseOverDockPanelBackImageUrl"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _DockPanelImage.FullName;
                    setter.Property = System.Windows.Controls.StackPanel.BackgroundProperty;
                    setter.Value = this.GetImageBrush(Property.GetStringValue("MouseOverDockPanelBackImageUrl"));
                    trigger.Setters.Add(setter);
                }

                if (Property.ContainsKey("MouseOverBackColor"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _PanelFullName;
                    setter.Property = System.Windows.Controls.StackPanel.BackgroundProperty;
                    setter.Value = this.GetColor(Property.GetStringValue("MouseOverBackColor"));
                    trigger.Setters.Add(setter);
                }

                if (Property.ContainsKey("MouseOverFontColor"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _Label != null ? _Label.FullName : _TextBlock.FullName;
                    setter.Property = System.Windows.Controls.TextBlock.ForegroundProperty;
                    setter.Value = new System.Windows.Media.SolidColorBrush(Utility.Common.GetColor(Property.GetStringValue("MouseOverFontColor")));
                    trigger.Setters.Add(setter);
                }

                if (Property.ContainsKey("MouseOverBackImageUrl"))
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _PanelFullName;
                    setter.Property = System.Windows.Controls.StackPanel.BackgroundProperty;
                    setter.Value = this.GetImageBrush(Property.GetStringValue("MouseOverBackImageUrl"));
                    trigger.Setters.Add(setter);
                }

                if (_IsButtonStatus)
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _PanelFullName;
                    setter.Property = System.Windows.Controls.StackPanel.OpacityProperty;
                    setter.Value = 0.8;
                    trigger.Setters.Add(setter);
                }

                triggers.Add(trigger);
            }

            if (Property.GetValue<bool>("IsPressed"))
            {
                trigger = new System.Windows.Trigger() { Property = System.Windows.Controls.Button.IsPressedProperty, Value = true };

                if (_IsButtonStatus)
                {
                    System.Windows.Setter setter = new System.Windows.Setter();
                    setter.TargetName = _PanelFullName;
                    setter.Property = System.Windows.Controls.StackPanel.OpacityProperty;
                    setter.Value = 0.9;
                    trigger.Setters.Add(setter);
                }

                triggers.Add(trigger);
            }

            trigger = new System.Windows.Trigger() { Property = System.Windows.Controls.Button.IsEnabledProperty, Value = false };

            System.Windows.Setter setter2 = new System.Windows.Setter();
            setter2.TargetName = _PanelFullName;
            setter2.Property = System.Windows.Controls.StackPanel.BackgroundProperty;
            setter2.Value = GetColor("#f2f2f2");
            trigger.Setters.Add(setter2);

            if (_Label != null || _TextBlock != null)
            {
                setter2 = new System.Windows.Setter();
                setter2.TargetName = _Label != null ? _Label.FullName :_TextBlock.FullName;
                setter2.Property = System.Windows.Controls.Label.ForegroundProperty;
                setter2.Value = GetColor("#888888");
                trigger.Setters.Add(setter2);
            }

            if(_Image!= null)
            {
                setter2 = new System.Windows.Setter();
                setter2.TargetName = _Image.FullName;
                setter2.Property = System.Windows.Controls.Image.SourceProperty;
                setter2.Value = _Image.GetGrayImageSource();
                trigger.Setters.Add(setter2);
            }

            triggers.Add(trigger);
        }

        bool _IsButtonStatus { get; set; }

        private void SetProperty()
        {
            this.SetDefaultValue("IsClick", true);
            this.SetDefaultValue("Cursor", "Hand");
            this.SetDefaultValue("IsButtonStatus", true);

            _IsButtonStatus = Property.GetValue<bool>("IsButtonStatus");
            if (_IsButtonStatus)
            {
                this.SetDefaultValue("IsMouseOver", true);
                this.SetDefaultValue("IsPressed", true);
            }

            _LabelText = Property.GetStringValue("Label");
            if (string.IsNullOrEmpty(_LabelText)) _LabelText = Property.GetStringValue("Text");
        }

        public void SetImageUrl(string url)
        {
            var image = (System.Windows.Controls.Image)_Button.Template.FindName(_Image.FullName, _Button);
            if (image != null) image.Source = GetImage(url);
            else
            {
                Task.Run(() =>
                {
                    this._Window.Window.Dispatcher.Invoke(() =>
                    {
                        try
                        {
                            SetImageUrl(url);
                        }
                        catch
                        {
                        }
                    });
                });
            }
        }

        public void SetLabelBackColor(string color)
        {
            if (_Label != null)
            {
                var label = (System.Windows.Controls.Label)_Button.Template.FindName(_Label.FullName, _Button);
                if (label != null) label.Background = GetColor(color);
                else
                {
                    Task.Run(() =>
                    {
                        this._Window.Window.Dispatcher.Invoke(() =>
                        {
                            try
                            {
                                SetLabelBackColor(color);
                            }
                            catch
                            {
                            }
                        });
                    });
                }
            }
            else if (_TextBlock != null)
            {
                var label = (System.Windows.Controls.TextBlock)_Button.Template.FindName(_TextBlock.FullName, _Button);
                if (label != null) label.Background = GetColor(color);
                else
                {
                    Task.Run(() =>
                    {
                        this._Window.Window.Dispatcher.Invoke(() =>
                        {
                            try
                            {
                                SetLabelBackColor(color);
                            }
                            catch
                            {
                            }
                        });
                    });
                }
            }
        }

        public string GetLabelText()
        {
            return _LabelText;
        }

        string _LabelText { get; set; }

        public void SetFontColor(string color)
        {
            if (_Label != null)
            {
                var label = (System.Windows.Controls.Label)_Button.Template.FindName(_Label.FullName, _Button);
                if (label != null) label.Foreground = GetColor(color);
            }
            else if (_TextBlock != null)
            {
                var label = (System.Windows.Controls.TextBlock)_Button.Template.FindName(_TextBlock.FullName, _Button);
                if (label != null) label.Foreground = GetColor(color); ;
            }
        }

        public void SetLabelText(string text)
        {
            _LabelText = text;
            if (_Label != null)
            {
                var label = (System.Windows.Controls.Label)_Button.Template.FindName(_Label.FullName, _Button);
                if (label != null) label.Content = text;
                else
                {
                    Task.Run(() =>
                    {
                        this._Window.Window.Dispatcher.Invoke(() =>
                        {
                            try
                            {
                                SetLabelText(text);
                            }
                            catch
                            {
                            }
                        });
                    });
                }
            }
            else if (_TextBlock != null)
            {
                var label = (System.Windows.Controls.TextBlock)_Button.Template.FindName(_TextBlock.FullName, _Button);
                if (label != null) label.Text = text;
                else
                {
                    Task.Run(() =>
                    {
                        this._Window.Window.Dispatcher.Invoke(() =>
                        {
                            try
                            {
                                SetLabelText(text);
                            }
                            catch
                            {
                            }
                        });
                    });
                }
            }
        }

        List<string> _NoContainNameList { get; set; }

        protected override void SetProperty(string name, object value)
        {
            System.Windows.Controls.Button c = _Button;
            switch (name)
            {
                case "name": c.Name = string.Concat("btn_", (string)value); break;
                case "Width": c.Width = Convert.ToDouble(value); break;
                case "Height": c.Height = Convert.ToDouble(value); break;
                case "ControlAlign": SetControlAlign((string)value); break;
                case "Dock": System.Windows.Controls.DockPanel.SetDock(c, this.GetDock((string)value)); break;
                case "Margin": c.Margin = this.GetThickness((string)value); break;
                case "Visible": c.Visibility = (bool)value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed; break;
                case "Cursor": c.Cursor = GetCursor((string)value); break;
                case "ZIndex": SetZIndex(Convert.ToInt32(value)); break;
                case "CanvasLocation": SetCanvasLocation((string)value); break;
                case "CanvasZIndex": SetCanvasZIndex(Convert.ToInt32(value)); break;
                case "IsEnabled": c.IsEnabled=(bool)value;break;
            }
        }

        public void SetEnabled(bool isEnabled)
        {
            if (_Button.IsEnabled == isEnabled) return;
            _Button.IsEnabled= isEnabled;
        }

        /// <summary>
        /// 事件加载
        /// </summary>
        public override void EventLoad()
        {
            bool isClick = this.Property.GetValue<bool>("IsClick");
            if (isClick) this._Button.Click += _Button_Click;
        }

        void _Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                if (_DataGridViewControls != null) _DataGridViewControls.DataGridView.EventInvoke(sender, e, this, "RowButtonClick");
                if (ClickAction != null) ClickAction(sender, e, this);
                else this._Window.EventInvoke(sender, e, this);
            }
            catch (Exception ex)
            {
                LoggerProxy.Exception(Name, "_Button_Click", ex);
            }
        }
    }
}
